#ifndef SCON_PROFILE_TEST_H_
#define SCON_PROFILE_TEST_H_

#include "gtest/gtest.h" 

#include "scon_file.h"

namespace SCon {

class ProfileTest: public ::testing::Test {
public:
	std::string errorMessage;
	std::string* pErrorMessage;

	virtual void SetUp() {
		errorMessage = "";
		pErrorMessage = &errorMessage;
	}//end of virtual void SetUp()

	virtual void TearDown() {}//end of virtual void TearDown()
};//end of declaration class ProfileTest: public ::testing::Test

TEST_F(ProfileTest, FileCreateTest){
//тестируем функцию File::Create()
	File* f;
	std::string path = "C:\\test.txt";
	//проверим, что открывается с флагом File::RECREATE
	f = File::Create(path, File::RECREATE | File::READ, pErrorMessage);
	EXPECT_TRUE(f->fileDescriptor_ != 0);
	EXPECT_EQ(f->path_.c_str(), path.c_str());
	CloseHandle(f->fileDescriptor_);
	delete(f);
	HANDLE test = CreateFile(path.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
	EXPECT_TRUE(test != INVALID_HANDLE_VALUE);
	CloseHandle(test);
	//проверим, что с флагом File::OPEN новый файл не создается
	std::string path1 = "C:\\test1.txt";
	f = File::Create(path1, File::OPEN | File::READ, pErrorMessage);
	EXPECT_TRUE(f == 0);
	EXPECT_TRUE(errorMessage != "");
}

TEST_F(ProfileTest, FileCloseTest){
//тестируем функцию File::Close()
	std::string path = "C:\\test.txt";
	File* f = File::Create(path, File::RECREATE | File::READ, pErrorMessage);
	bool noError = File::Close(f, pErrorMessage);
	EXPECT_TRUE(noError);
	f = File::Create(path, File::RECREATE | File::READ, pErrorMessage);
	CloseHandle(f->fileDescriptor_);
	noError = File::Close(f, pErrorMessage);
	EXPECT_TRUE(!noError);
	EXPECT_TRUE(errorMessage != "");
}

TEST_F(ProfileTest, FileCheckParameterTest){
//проверяем функцию File::CheckParameter()
	bool result = File::CheckParameter(3, pErrorMessage);
	EXPECT_TRUE(!result);
	EXPECT_STREQ(pErrorMessage->c_str(), "Parameter out of range");

	result = File::CheckParameter(121, pErrorMessage);
	EXPECT_TRUE(!result);
	EXPECT_STREQ(pErrorMessage->c_str(), "Parameter out of range");

	result = File::CheckParameter(File::CREATE | File::RECREATE | File::OPEN | File::READ, pErrorMessage);
	EXPECT_TRUE(!result);
	EXPECT_STREQ(pErrorMessage->c_str(), "Flags CREATE, OPEN and RECREATE can not be specified together");

	result = File::CheckParameter(File::CREATE | File::OPEN | File::READ, pErrorMessage);
	EXPECT_TRUE(!result);
	EXPECT_STREQ(pErrorMessage->c_str(), "Flags CREATE, OPEN and RECREATE can not be specified together");

	result = File::CheckParameter(File::CREATE | File::RECREATE | File::READ, pErrorMessage);
	EXPECT_TRUE(!result);
	EXPECT_STREQ(pErrorMessage->c_str(), "Flags CREATE, OPEN and RECREATE can not be specified together");

	result = File::CheckParameter(File::RECREATE | File::OPEN | File::READ, pErrorMessage);
	EXPECT_TRUE(!result);
	EXPECT_STREQ(pErrorMessage->c_str(), "Flags CREATE, OPEN and RECREATE can not be specified together");

	result = File::CheckParameter(File::READ | File::SHARED_READ, pErrorMessage);
	EXPECT_TRUE(!result);
	EXPECT_STREQ(pErrorMessage->c_str(), "Creation mode and access mode can be specified");

	result = File::CheckParameter(File::CREATE | File::SHARED_READ, pErrorMessage);
	EXPECT_TRUE(!result);
	EXPECT_STREQ(pErrorMessage->c_str(), "Creation mode and access mode can be specified");
}

TEST_F(ProfileTest, FileCalculateSharedModeTest){
//Проверим, что функция File::CalculateSharedMode()
//генерирует нужные значения
	File f;
	int sharedMode;
	sharedMode = f.CalculateSharedMode(File::SHARED_READ);
	EXPECT_EQ(sharedMode, FILE_SHARE_READ);
	sharedMode = f.CalculateSharedMode(File::SHARED_WRITE);
	EXPECT_EQ(sharedMode, FILE_SHARE_WRITE);
	sharedMode = f.CalculateSharedMode(File::SHARED_READ | File::SHARED_WRITE);
	EXPECT_EQ(sharedMode, FILE_SHARE_READ | FILE_SHARE_WRITE);
	sharedMode = f.CalculateSharedMode(File::SHARED_READ | File::SHARED_WRITE | File::CREATE);
	EXPECT_EQ(sharedMode, FILE_SHARE_READ | FILE_SHARE_WRITE);
	sharedMode = f.CalculateSharedMode(0);
	EXPECT_EQ(sharedMode, 0);
}

TEST_F(ProfileTest, FileCalculateOpenModeTest){
//проверим, что функция File::CalculateOpenMode()
//генерирует нужные значения
	File f;
	int openMode = 0;
	openMode = f.CalculateOpenMode(File::RECREATE);
	EXPECT_EQ(openMode, CREATE_ALWAYS);
	openMode = f.CalculateOpenMode(File::CREATE);
	EXPECT_EQ(openMode, CREATE_NEW);
	openMode = f.CalculateOpenMode(File::OPEN);
	EXPECT_EQ(openMode, OPEN_EXISTING);
	openMode = f.CalculateOpenMode(File::OPEN | File::RECREATE);
	EXPECT_EQ(openMode, CREATE_ALWAYS);
	openMode = f.CalculateOpenMode(File::OPEN | File::CREATE);
	EXPECT_EQ(openMode, CREATE_NEW);
	openMode = f.CalculateOpenMode(File::OPEN | File::SHARED_WRITE);
	EXPECT_EQ(openMode, OPEN_EXISTING);
}

TEST_F(ProfileTest, FileCalculateAccessModeTest){
//проверим, что функция File::CalculateAccessMode()
//генерирует нужные знаяения
	File f;
	int accessMode = 0;
	accessMode = f.CalculateAccessMode(File::READ);
	EXPECT_EQ(accessMode, GENERIC_READ);
	accessMode = f.CalculateAccessMode(File::WRITE);
	EXPECT_EQ(accessMode, GENERIC_WRITE);
	accessMode = f.CalculateAccessMode(File::READ | File::OPEN);
	EXPECT_EQ(accessMode, GENERIC_READ);
	accessMode = f.CalculateAccessMode(File::READ | File::WRITE | File::OPEN);
	EXPECT_EQ(accessMode, GENERIC_READ | GENERIC_WRITE);
}

} /* SCon */ 

#endif /* end of include guard: SCON_PROFILE_TEST_H_ */

